import util from '../other/util';
import optionSide from '../other/optionSide'

let verify = {};

verify.is = util.is;
var rules = util.rules;

var radioItem = function (key, data, parent) {
    this.parent = parent;
    this.data = data;
    this.name = data[key];
    var html = '';
    html += '<div class="form_radio_Item">';
    html += '   <label class="form_radio_choose"><i class="fa fa-circle-o"></i></label>';
    html += '   <div class="form_radio_name">' + this.name + '</div>';
    html += '</div>';
    // fa-dot-circle-o
    this.html = $(html);
    this._element = this.html.find('.form_radio_choose');
    this.selectStutas = false;
    var _this = this;
    this.html.unbind().bind('click', function () {
        _this.parent.change(_this);
    });
};
radioItem.prototype = {
    constructor: this,
    select: function () {
        this.valueData = true;
        this._element.addClass('active');
        this._element.find('i').removeClass('fa-circle-o').addClass('fa-dot-circle-o');

        this.html.unbind();
    },
    unSelect: function () {
        var _this = this;
        this._element.removeClass('active');
        this._element.find('i').removeClass('fa-dot-circle-o').addClass('fa-circle-o');
        this.html.unbind().bind('click', function () {
            _this.parent.change(_this);
        });
    },
};
var radio = function (options) {
    if (options === undefined) {
        options = {};
    };
    var _this = this;
    this.options = $.extend({}, {
        className: '', // 自定义元素样式
        verify: {  // 验证判断组
            text: '',
            rules: []
        },
        showKey: 'label', // 根据子对象的数据Key值进行显示
        setKey: 'value', // 根据子对象的数据Key值进行赋值
        getKey: 'setKey', // 根据子对象的数据Key值进行取值
        "default": null, // 默认值
        readonly: false, // 是否只读
        data: [], // 数据来源
        onChange: function () { }, // 当值发生改变时,调用方法
        onError: function () { } // 当值发生错误时(不符合验证时),调用方法
    }, options);
    this.child = [];
    this.valueData = null;
    this.value = null;
    this.cache = null;
    this.errorMessage = null;
    this.html = $('<div class="form_radio"></div>');
    if (this.options.data.length != 0) {
        this.setData(this.options.data);
    };
    // 事件集合
    this.event = {
        change: this.options.onChange,
        error: this.options.onError
    };
    this.readonly(this.options.readonly);
};
radio.prototype = {
    constructor: this,
    on: function (str, event) {
        if (this.event.hasOwnProperty(str)) {
            this.event[str] = event;
        };
        return this;
    },
    // 单独绑定 change 方法
    onChange: function (event) {
        this.event.change = event;
        return this;
    },
    // 单独绑定 error 方法
    onError: function (event) {
        this.event.error = event;
        return this;
    },
    // 遍历子对象方法
    eachChild: function (event) {
        for (var i = 0; i < this.child.length; i++) {
            var element = this.child[i];
            event(element);
        };
        return this;
    },
    readonly: function (isReadonly) {
        var _isReadonly = null;
        if (verify.is(isReadonly) == 'function') {
            _isReadonly = isReadonly();
        };
        _isReadonly = !!isReadonly;
        var _this = this;
        if (isReadonly) {
            this.eachChild(function (child) {
                child.html.unbind('click');
            });
        } else {
            this.eachChild(function (child) {
                child.html.unbind().bind('click', function () {
                    _this.change(child);
                });
            });
        };
    },
    setData: function (data) {
        this.child = [];
        var _data = $.extend([], {}, data);
        this.html.empty();
        this.valueData = null;
        var dataType = verify.is(data);
        if (dataType == 'string' && data.indexOf('OptionSide:') != -1) {
            _data = optionSide.get(data.split(':')[1]);
        };
        if (_data.length == 0) {
            console.error('Select => 选择项赋值失败 : ' + data);
        };
        this.options.data = _data;
        if (this.options.showUnSelect) {
            var UnSelectData = {};
            UnSelectData[this.options.setKey] = this.options.UnSelectData.data;
            UnSelectData[this.options.getKey] = this.options.UnSelectData.data;
            UnSelectData[this.options.showKey] = this.options.UnSelectData.showName;
            this.options.data.unshift(UnSelectData);
        };

        if (dataType == 'array' || verify.is(_data, 'array')) {
            for (var i = 0; i < _data.length; i++) {
                var item = _data[i];
                var child = new radioItem(this.options.showKey, item, this);
                this.child.push(child);
                this.html.append(child.html);
            };
        };
        this.defaultValue().readonly(this.options.readonly);
        return this;
    },
    // 清除选择方法
    clear: function () {
        this.valueData = null;
        this.value = null;
        this.eachChild(function (child) {
            child.unSelect();
        });
        return this;
    },
    // 赋值方法
    set: function (data) {
        if (data === null) {
            this.clear();
        } else {
            var isComplete = false;
            var dataType = verify.is(data);
            if (dataType == 'array') {
                this.clear();
                this.setData(data);
                isComplete = true;
            } else {
                if (this.child.length === 0) {
                    this.cache = data;
                    isComplete = true;
                } else {
                    var _this = this;
                    if (dataType == 'string' || dataType == 'number') {
                        this.clear().eachChild(function (clild) {
                            if (data == clild.data[_this.options.setKey]) {
                                _this.select(clild);
                                isComplete = true;
                            };
                        });
                    } else if (dataType == 'object') {
                        this.clear().eachChild(function (clild) {
                            if (verify.isEqual(clild.data, data)) {
                                _this.select(clild);
                            };
                        });
                        isComplete = true;
                    } else if (dataType == 'number') {
                        if (this.child[data]) {
                            this.clear();
                            _this.select(this.child[data]);
                            isComplete = true;
                        };
                    };
                };
            };
            if (!isComplete) {
                console.error('select => set 错误 : 未找到指定的值');
            };
        };
        return this;
    },
    // 赋予默认值方法
    defaultValue: function () {
        if (this.options['default'] === null) {
            this.clear();
        } else {
            this.set(this.options['default']);
        };
        return this;
    },
    // 验证方法
    verify: function () {
        if (this.options.getKey != 'object') {
            var text = rules(this.options.verify, this.value);
            // 如果错误信息不为空,则触发error方法,并保留错误信息
            if (text) {
                this.event.error.apply(this, [text, this.value]);
                this.errorMessage = text;
            } else {
                // 如果错误信息为空,侧清空错误信息
                this.errorMessage = null;
            };
        };
        return this;
    },
    // 选中方法
    select: function (childObject) {
        this.valueData = childObject.data;
        if (this.options.getKey == 'object') {
            this.value = this.valueData;
        } else if (this.options.getKey == 'setKey') {
            this.value = this.valueData[this.options.setKey];
        } else if (this.valueData.hasOwnProperty(this.options.getKey)) {
            this.value = this.valueData[this.options.getKey];
        } else {
            console.error('select => select 错误 : 错误的取值类型');
        };
        childObject.select();
        return this;
    },
    // 当元素改变时触发事件
    change: function (childObject) {
        this.clear().select(childObject);
        this.event.change.apply(this, [this.value]);
        this.verify();
        return this;
    },
    get: function (callBack, ignore) {
        if (ignore) {
            callBack(this.value);
        } else {
            this.verify();
            if (this.errorMessage) {
                callBack(this.errorMessage);
            } else {
                callBack(false, this.value);
            };
        };
        return this;
    },
    radioItem: radioItem,
};

export default radio